;;;name:BF-list+
;;;desc:两个列表各项相加之和组成的列表，列表长度以参数中列表长度小的为准
;;;arg:lst1:数字列表
;;;arg:lst2:数字列表
;;;return:列表各项相加后的列表
;;;example:(BF-list+ '(1 2) '(3 4))
(defun BF-list+	(lst1 lst2)
  (mapcar '+ lst1 lst2)
)
;;;name:BF-list-
;;;desc:两个列表各项差组成的列表，列表长度以参数中列表长度小的为准
;;;arg:lst1:数字列表
;;;arg:lst2:数字列表
;;;return:列表各项相减后的列表
;;;example:(BF-list- '(1 2) '(3 4))
(defun BF-list-	(lst1 lst2)
  (mapcar '- lst1 lst2)
)

;;;name:BF-list-split-3d
;;;desc:列表按顺序切分为3元素表组成的表,不足部分用nil表示
;;;arg:lst:列表
;;;return:((x x x )(x x x)...)
;;;example:(BF-list-split-3d '(1 2 3 4))
(defun BF-list-split-3d	(lst)
  (if lst
    (cons
      (list
				(car lst)
				(cadr lst)
				(caddr lst)
      )
      (BF-list-split-3d (cdddr lst))
    )
  )
)
;;;name:BF-list-split-2d
;;;desc:列表按顺序切分为2元素表组成的表,不足部分用nil表示
;;;arg:lst:列表
;;;return:((x x )(x x )...)
;;;example:(BF-list-split-2d '(1 2 3 4))
(defun BF-list-split-2d	(lst)
  (if lst
    (cons
      (list
				(car lst)
				(cadr lst)
      )
      (BF-list-split-2d (cddr lst))
    )
  )
)

;;;name:BF-list-split
;;;desc:列表切分,不足部分省略，此函数返回结果相对BF-list-split-2d、BF-list-split-3d两个特殊函数比较合理
;;;arg:lst:列表
;;;arg:x:每组的元素个数
;;;return:切分后的列表
;;;example:(BF-list-split '(1 2 3 4) 3)
(defun BF-list-split (lst x / lst2)
  (foreach n lst
    (if	(and lst2 (/= x (length (car lst2))))
      (setq lst2 (cons (append (car lst2) (list n)) (cdr lst2)))
      (setq lst2 (cons (list n) lst2))
    )
  )
  (reverse lst2)
)


;;;name:BF-dot->list
;;;desc:点表转普通表
;;;arg:lst:点表
;;;return:普通表
;;;example:(BF-dot->list '(1 2 3 . 4))
(defun BF-dot->list (lst)
  (if (BF-listp lst)
    lst
    (cond
      ((and lst (listp lst))
				(cons (car lst) (BF-dot->list (cdr lst)))
      )
      ((and lst (not (listp lst)))
				(cons lst (BF-dot->list nil))
      )
      (t nil)
    )
  )
)

;;;name:BF-indot->list
;;;desc:内嵌点表的表转普通表
;;;arg:lst:内嵌点表
;;;return:普通表
;;;example:(BF-indot->list '(1 2 (3 . 4)))
(defun BF-indot->list (lst / tmplist)
  (setq tmplist lst)
  (foreach i tmplist
    (if	(BF-DotPairp i)
      (setq lst (subst (BF-dot->list i) i lst))
    )
  )
  lst
)
;;;name:BF-List-range
;;;desc:生成等差数列表，类似python的range()函数
;;;arg:start:起始值
;;;arg:end:结束值
;;;arg:step:等差值
;;;return:等差数列表
;;;example:(BF-List-range 1 4 1) --> (1 2 3)
(defun BF-List-range (start end step)
  (if (= start end)
    (quote ())
    (cons start (BF-List-range (+ start step) end step))))

;;;name:BF-list-exist
;;;desc:判断item是否在列表内，
;;;arg:lst:列表，任意嵌套表
;;;arg:item:被检查的元素
;;;return:存在t，反之nil
;;;example:(BF-list-exist '(1 2 3 4) 3)
(defun BF-list-exist (lst item)
  (apply
    'or
    (cons
      (vl-position item lst)
      (mapcar '(lambda (x) (BF-list-exist x item))
	      (vl-remove-if 'atom lst)
      )
    )
  )
)

;;;name:BF-list-Search-Index
;;;desc:以索引查找表中元素
;;;arg:lst:列表
;;;arg:index:索引或者索引表
;;;return:查找到的元素组成的表
;;;example:(BF-list-Search-Index '(1 2 3 4) 3)
(defun BF-list-Search-Index (lst index)
  (mapcar '(lambda (x) (nth x lst))
	  (if (atom index)
	    (list index)
	    index
	  )
  )
)
;;;name:BF-list-search-item
;;;desc:查找表中元素的索引，索引从0开始
;;;arg:lst:列表
;;;arg:item:元素
;;;return:索引值表
;;;example:(BF-list-search-item '(1 2 3 4) 3)
(defun BF-list-search-item (lst item / i result)
  (setq i 0)
  (foreach x lst
    (if (= x item)
      (setq result (cons i result))
    )
    (setq i (1+ i))
  )
  (reverse result)
)
;;;名称:BF-List-RemoveIndex
;;;说明:按索引删除列表的项,leemac
;;;参数:lst:列表
;;;参数:index:索引，从0开始
;;;返回:删除索引项之后的列表
;;;示例:(BF-List-RemoveIndex '(0 1 2 3) 1)
(defun BF-List-RemoveIndex (lst index / i)
  (setq i -1)
  (vl-remove-if '(lambda (x) (= (setq i (1+ i)) index)) lst)
)

;;;name:BF-list-RemoveOnce
;;;desc:删除表中第一个匹配到的元素,leemac
;;;arg:lst:列表
;;;arg:item:元素
;;;return:删除元素后的表
;;;example:(BF-list-RemoveOnce '(1 2 3 4) 3)
(defun BF-list-RemoveOnce (lst item / f)
  (setq f equal)
  (vl-remove-if
    '(lambda (a)
       (if (f a item)
				 (setq f (lambda (a b) nil))
       )
     )
    lst
  )
)

;;;name:BF-AssocList-Remove
;;;desc:删除表中关联表匹配到key的的子表
;;;arg:lst:列表
;;;arg:key:关键字
;;;return:删除元素后的表
;;;example:(BF-AssocList-Remove '((1 11) (2 22) (3 33) (4 44)) 2) ==>((1 11) (3 33) (4 44))

(defun BF-AssocList-Remove (lst key)
  (vl-remove-if '(lambda (x) (equal (car x) key)) lst)
)

;;;name:BF-AssocList-Index
;;;desc:根据key查找关联表的索引
;;;arg:lst:关联表
;;;arg:key:关键字
;;;return:索引，从0开始
;;;example:(BF-AssocList-Index '((1 11) (2 22) (3 33) (4 44)) 3) ==> 2
(defun BF-AssocList-Index (lst key)
	(vl-position key (mapcar 'car lst))
)
;;;name:BF-AssocList-AddItem
;;;desc:添加关联表的元素,无替换
;;;arg:lst:关联表
;;;arg:value:值表
;;;return:关联表，无相同的key
;;;example:(BF-AssocList-AddItem '((1 11) (2 22) (3 33) (4 44)) '(2 33))
(defun BF-AssocList-AddItem (lst value)
	(if (assoc (car value) lst)
		lst
		(cons value lst)
	)
)
;;;name:BF-AssocList-AppendItem
;;;desc:添加关联表的元素,替换
;;;arg:lst:关联表
;;;arg:value:值表
;;;return:关联表，无相同的key
;;;example:(BF-AssocList-AppendItem '((1 11) (2 22) (3 33) (4 44)) '(2 33))
(defun BF-AssocList-AppendItem (lst value)
	(if (assoc (car value) lst)
		(setq lst (BF-AssocList-Remove lst (car value)))
	)
	(cons value lst)
)

(defun BF-AssocList-AppendList (lst value)
	(if (listp value)
		(foreach item value
			(setq lst (BF-AssocList-AppendItem lst item))
		)
	)
)


;;;函数名称:BF-AssocList-Keys
;;;函数说明:返回关联表的key值表
;;;参    数:lst:关联表
;;;返 回 值:key值表
;;;示    例:(BF-AssocList-Keys lst)
(defun BF-AssocList-Keys (lst)
	(mapcar 'car lst)
)

;;;函数名称:BF-AssocList-Values
;;;函数说明:返回关联表的value值表
;;;参    数:lst:关联表
;;;返 回 值:value值表
;;;示    例:(BF-AssocList-Values lst)
(defun BF-AssocList-Values (lst)
	(mapcar 'cdr lst)
)

;;;函数名称:BF-AssocList-Key
;;;函数说明:返回关联表中key对应的value
;;;参    数:lst:关联表
;;;参    数:key:关键字
;;;返 回 值:key对应的value
;;;示    例:(BF-AssocList-Key lst key)
(defun BF-AssocList-Key (lst key)
	(cdr (assoc key lst))
)

;;;名称:BF-List-ChangeIndex
;;;说明:交换列表的m和n项，索引从0开始
;;;参数:lst:列表
;;;参数:m:索引
;;;参数:n:索引
;;;返回:交换后的列表
;;;示例:(BF-List-ChangeIndex '(0 1 2 3) 1 2)
(defun BF-List-ChangeIndex (lst m n / t1 t2)
  (setq	t1 (nth m lst)
		t2 (nth n lst)
  )
  (BF-List-ReplaceIndex (BF-List-ReplaceIndex lst m t2) n t1)
)








;;;名称:BF-List-ltrim
;;;说明:删除表头前m项
;;;参数:lst:列表
;;;参数:m:要删除的数量
;;;返回:删除前m项后的列表
;;;示例:(BF-List-ltrim '(0 1 2 3) 1)
(defun BF-List-ltrim (lst m)
  (cond	((or
					 (zerop m)
					 (minusp m)
					 (>= m (length lst))
				 )
					lst
				)
		(t
			(repeat m
				(setq lst (cdr lst))
			)
		)
  )
)

;;;名称:BF-list-rtrim
;;;说明:删除表尾前m项
;;;参数:lst:列表
;;;参数:m:要删除的数量
;;;返回:删除后m项后的列表
;;;示例:(BF-list-rtrim '(0 1 2 3) 1) ==> (0 1 2)
(defun BF-list-rtrim (lst m)
  (reverse (BF-List-ltrim (reverse lst) m))
)
;;;名称:BF-list-trim
;;;说明:删除表头前m项，表尾前n项
;;;参数:lst:列表
;;;参数:m:表头要删除的数量
;;;参数:n:表尾要删除的数量
;;;返回:删除后的列表
;;;示例:(BF-list-trim '(0 1 2 3) 1 1)
(defun BF-List-Trim (lst m n)
  (BF-List-ltrim (BF-list-rtrim lst n) m)
)


;;;name:BF-list-split-index
;;;desc:根据索引分割列表，索引从0开始
;;;arg:lst:列表
;;;arg:index:索引值
;;;return:索引前后元素组成的表，其中索引所指向的元素位于第二个子表的表头
;;;example:(BF-list-split-index '(1 2 3 4) 2)
(defun BF-list-split-index (lst index / result tmp)
  (setq tmp lst)
  (repeat index
    (setq result (cons (car tmp) result))
    (setq tmp (cdr tmp))
  )
  (list (reverse result) (BF-list-ltrim lst index))
)

;;;名称:BF-List-sublist
;;;说明:获取子列表,leemac
;;;参数:lst:列表
;;;参数:idx:开始索引项
;;;参数:len:子列表长度
;;;返回:子列表
;;;示例:(BF-List-sublist '(0 1 2 3) 1 2)
(defun BF-List-sublist (lst idx len / rtn)
  (setq	len (if	len
							(min len (- (length lst) idx))
							(- (length lst) idx)
						)
		idx (+ idx len)
  )
  (repeat len
    (setq rtn (cons (nth (setq idx (1- idx)) lst) rtn))
  )
)


;;;名称:BF-List-Insert
;;;说明:插入项
;;;参数:lst:列表
;;;参数:index:索引，从0开始
;;;参数:item:项
;;;返回:插入项后的列表
;;;示例:(BF-List-Insert '(0 1 2 3) 1 5)
(defun BF-List-Insert (lst index item)
  (if (zerop index)
    (cons item lst)
    (cons (car lst)
			(BF-List-insert (cdr lst) (1- index) item)
    )
  )
)


;;;名称:BF-List-ReplaceIndex
;;;说明:按索引替换列表
;;;参数:oldlst:被替换的列表
;;;参数:index:索引，从0开始
;;;参数:item:值
;;;返回:替换后的列表
;;;示例:(BF-List-ReplaceIndex '(0 1 2 3) 1 5)
(defun BF-List-ReplaceIndex (oldlst index item)
  (if (zerop index)
    (append (list item) (cdr oldlst))
    (cons (car oldlst)
			(BF-list-replaceindex (cdr oldlst) (1- index) item)
    )
  )
)
;;;名称:BF-List-Replace[m,n]
;;;说明:按索引替换列表第m子表的第n项
;;;参数:oldlst:被替换的列表
;;;参数:m:索引，从0开始
;;;参数:n:索引，从0开始
;;;参数:item:值
;;;返回:替换后的列表
;;;示例:(BF-List-Replace[m,n] '((1 11) (2 22) (3 33) (4 44)) 2 1 44) ==>((1 11) (2 22) (3 44) (4 44))
(defun BF-List-Replace[m,n] (oldlst m n item)
	(BF-List-ReplaceIndex oldlst m (BF-List-ReplaceIndex (nth m oldlst) n item))
)

;;;name:BF-list-subst
;;;desc:置换表中指定位置的元素
;;;arg:n:如果为两个元素的表，则代表第几个子表的第几项，项目均以0开始计数。如果为数字，则代表替换的表中的元素位置。
;;;arg:a:要替换为的子表。
;;;arg:l:要进行替换的表。
;;;return:替换后的表
;;;example:(SUBST-N '(0 2) '(99 22) '((1 2 3) 2 55 99 66)) ---->((1 2 (99 22)) 2 55 99 66)替换第一个子表第三项
;;;(SUBST-N '(2 1) '(99) '(1 2 (55) 99 66)) ----> (1 2 (55 ((99))) 99 66) 替换第三个子表第二项
;;;(SUBST-N 2.0 '(99) '(1 2 55 99 66)) ----> (1 2 (99) 99 66) 替换第三个原素
(defun BF-list-subst (n a l)
  (cond
    ((numberp n)
			(if (zerop n)
				(append (list a) (cdr l))
				(cons (car l) (BF-list-subst (1- n) a (cdr l)))
			)
    )
    ((listp n)
			(cond
				((equal (length n) 1)
					(if (zerop (car n))
						(append (list a) (cdr l))
						(cons (car l) (BF-list-subst (1- (car n)) a (cdr l)))
					)
				)
				((> (length n) 1)
					(if (zerop (car n))
						(cons (BF-list-subst (cdr n) a (car l)) (cdr l))
						(cons	(car l)
							(BF-list-subst
								(append (list (1- (car n))) (cdr n))
								a
								(cdr l)
							)
						)
					)
				)
			)
    )
  )
)



;;;name:BF-list-same
;;;desc:查找表中重复元素
;;;arg:lst:列表
;;;return:重复元素组成的表
;;;example:(BF-list-same '(0 1 2 3 2 4 4))---->(2 4)
(defun BF-list-same (lst)
  (if lst
		(if (member (car lst) (cdr lst))
			(cons (car lst) (BF-list-same (vl-remove (car lst) (cdr lst))))
			(BF-list-same (vl-remove (car lst) (cdr lst)))
		)
	)
)

;;;name:BF-list-delnotsame
;;;desc:查找表中不重复元素
;;;arg:lst:列表
;;;return:重复元素组成的表
;;;example:(BF-list-delnotsame '(1 1 2 3 3 4 5 5 6))---->(1 1 3 3 5 5)
(defun BF-list-delnotsame (lst)
  (BF-math-intersect lst (BF-list-same lst))
)


;;;name:BF-list-delsame
;;;desc:删除表中相同元素，保留第一次出现的位置
;;;arg:lst:列表
;;;arg:buzz:容差
;;;return:删除重复元素组成的表
;;;example:(BF-list-delsame '(0 1 2 3 2 4 4) 0.1)---->(0 1 2 3 4)
(defun BF-list-delsame (lst buzz)
  (if Lst
    (cons (car Lst)
			(BF-list-delsame
				(vl-remove-if
					'(lambda (x) (equal (car lst) x buzz))
					(cdr lst)
				)
				buzz
			)
    )
  )
)


;;;name:BF-list-Same-num
;;;desc:表中相同元素及数量
;;;arg:lst:列表
;;;return:重复元素及数量组成的表
;;;example:(BF-list-same-num '(1 2 2 3 4 2 4 5 2 6 7)) ---> ((2 4) (4 2))
(defun BF-list-Same-num	(lst / l2 tmp)
  (while
    (setq tmp (vl-remove (car lst) lst)
			l2  (if (member (car lst) (cdr lst))
						(cons
							(list	(car lst)
								(- (length lst) (length tmp))
							)
							l2
						)
						l2
					)
			lst tmp
    )
  )
  (reverse l2)
)
;;;name:BF-list-item-num
;;;desc:表中元素及数量
;;;arg:lst:列表
;;;return:元素及数量组成的表
;;;example:(BF-list-item-num '(1 2 2 3 4 2 4 5 2 6 7))->((7 1) (6 1) (5 1) (4 2) (3 1) (2 4) (1 1))
(defun BF-list-item-num	(lst / l2 tmp tmp1)
  (while
    (setq l2  
			(cons
				(list 
			    (setq tmp1 (car lst))
					(- (length lst) (length (setq tmp (vl-remove tmp1 lst)))))
				l2)
			lst tmp
    )
  )
  (reverse l2)
)

;;;name:BF-list-delsame-all
;;;desc:删除表中所有重复的元素
;;;arg:lst:列表
;;;return:删除重复元素后的表
;;;example:(BF-list-delsame-all '(1 2 2 3 4 2 4 5 2 6 7))->(1 3 5 6 7)
(defun BF-list-delsame-all (lst)
    (vl-remove-if
        '(lambda (x) (member x (BF-list-same lst)))
        lst
    )
)


;;;name:BF-List-move
;;;desc:列表循环移动
;;;arg:lst:列表
;;;arg:n:移动次数，正数为左移，负数为右移
;;;return:移动后的表
;;;example:(BF-List-move '(1 2 2 3 4 2 4 5 2 6 7) -1) -> (7 1 2 2 3 4 2 4 5 2 6)
(defun BF-List-move (lst n)
  (repeat (abs n)
    (if	(minusp n)
      (setq lst (append (list (last lst)) (BF-list-rtrim lst 1)))
      (setq lst (append (cdr lst) (list (car lst))))
    )
  )
)


;;;name:BF-list-GetUbound
;;;desc:得到表的各维数长度，最多支持到三维
;;;arg:lst:表或原子
;;;return:各维长度组成的表
;;;example:(BF-list-GetUbound '(((1 2 3) (1 2))((1 2 3) (1 2))((1 2 3) (1 2))(((1 2 3) 2 3) (1 2)))) →(4 2 3)
(defun BF-list-GetUbound (lst)
  (if (atom lst)
    '(0 0 0)
    (list
      (vl-list-length lst)
      (apply 'max (mapcar 'vl-list-length lst))
      (apply 'max (mapcar 'vl-list-length (apply 'append lst)))
    )
  )
)
;;;名称:BF-List-rm-m2n
;;;说明:删除列表的第m至n项，索引值从0计算
;;;参数:lst:列表
;;;参数:m:索引，从0开始
;;;参数:n:索引，从0开始
;;;返回:删除后的列表
;;;示例:(BF-List-rm-m2n '(0 1 2 3 4) 1 2) ==>(0 3 4)
(defun BF-List-rm-m2n (lst m n / len i)
  (cond 
		((< m 0) (setq m 0))
		((> n (setq len (length lst)))(setq n len))
	)
	(setq i -1)
	(vl-remove-if '(lambda (x) (and (<= m (setq i (1+ i))) (<= i n)  )) lst)
)
